﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using WP7Client.ServerManager;
using WP7Client.Helpers;
using MSH.Common.DAO.Results;
using MSH.Common.Classes;
using System.Collections.Generic;
using MSH.Common.DAO;
using GalaSoft.MvvmLight.Command;
using System.Text;
using System.Diagnostics;

namespace WP7Client.Controller
{
    public class SocialNetworkAccountController : BaseController
    {
        private List<SocialNetworkAccount> accounts = new List<SocialNetworkAccount>();
        private Dictionary<String, String> accountLogoChecksums = new Dictionary<String, String>();
        private Dictionary<String, Byte[]> accountLogos = new Dictionary<String, Byte[]>();

        public SocialNetworkAccountController()
        {
            AuthenticateCommand = new RelayCommand<String>(Authenticate);
            RemoveCommand = new RelayCommand<String>(Remove);
        }

        public ICommand AuthenticateCommand
        {
            get;
            internal set;
        }

        public ICommand RemoveCommand
        {
            get;
            internal set;
        }

        public List<SocialNetworkAccount> Accounts
        {
            get { return accounts; }
            set 
            {
                Boolean cancel = false;
                String checksum = null;

                #region checkchecksum
                foreach (SocialNetworkAccount account in value)
                {
                    checksum = null;
                    if (account.Logo == null)
                    {
                        accountLogoChecksums.TryGetValue(account.Name, out checksum);
                        if (String.IsNullOrEmpty(checksum) || !checksum.Equals(account.LogoChecksum))
                        {
                            cancel = true;
                            break;
                        }
                        else
                        {
                            byte[] logo;
                            accountLogos.TryGetValue(account.Name, out logo);
                            account.Logo = logo;
                        }
                    }
                    else
                    {
                        accountLogoChecksums.TryGetValue(account.Name, out checksum);
                        if (!String.IsNullOrEmpty(checksum))
                        {
                            accountLogoChecksums.Remove(account.Name);
                            accountLogos.Remove(account.Name);
                        }
                        accountLogoChecksums.Add(account.Name, account.LogoChecksum);
                        accountLogos.Add(account.Name, account.Logo);
                    }
                }
                #endregion
                
                if (!cancel)
                {
                    accounts = value;
                    OnPropertyChanged("Accounts");
                }
                else
                    GetSocialNetworkAccounts(true);
            }
        }

        /// <summary>
        /// Haal het gekoppelde sociale netwerk op
        /// </summary>
        /// <param name="name">Naam van het sociale netwerk</param>
        /// <returns>Het gekoppelde sociale netwerk of null als er niks gekoppeld is</returns>
        private SocialNetworkAccount GetAccount(String name)
        {
            if (name == null)
                return null;
            foreach (SocialNetworkAccount account in Accounts)
            {
                if (account.Name.Equals(name))
                    return account;
            }
            return null;
        }

        /// <summary>
        /// Haal alle gekoppelde sociale netwerk accounts op
        /// </summary>
        /// <param name="includeLogos">Moeten de logo's erbij</param>
        private void GetSocialNetworkAccounts(Boolean includeLogos = false)
        {
            Loading = true;
            HttpGet httpGetSocialNetworkAccounts = new HttpGet(GlobalHelper.Url + String.Format("GetSocialNetworkAccounts/{0}/{1}", UserHelper.Token, includeLogos), typeof(GetSocialNetworkAccountsResult));
            httpGetSocialNetworkAccounts.FinishedGet += httpGetSocialNetworkAccounts_FinishedGet;
        }

        private void httpGetSocialNetworkAccounts_FinishedGet(object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get != null && (get.resultObject as GetSocialNetworkAccountsResult) != null)
                {
                    GetSocialNetworkAccountsResult result = (get.resultObject as GetSocialNetworkAccountsResult);
                    if (result.TokenValidationResult == TokenValidationResultEnum.Valid && result.Accounts != null)
                        Accounts = result.Accounts;
                }
            }
            catch (Exception ex) { }
            finally { Loading = false; }
        }

        /// <summary>
        /// Authenticeer het social netwerk account
        /// </summary>
        private SocialNetworkAccount CurrentSocialNetworkToAuthenticate = null;
        private void Authenticate(String name)
        {
            CurrentSocialNetworkToAuthenticate = null;
            Loading = true;
            SocialNetworkAccount account = GetAccount(name);
            if (account != null)
            {
                CurrentSocialNetworkToAuthenticate = account;
                ControllerHelper.WebBrowserSocialNetworkController.CurrentPageURL = account.AuthenticationURL;
                NavigationHelper.NavigateTo("/UserInterface/Pages/WebBrowserSocialNetworkPage.xaml");
            }
            Loading = false;
        }

        /// <summary>
        /// Verwijder een gekoppeld sociaal netwerk account
        /// </summary>
        /// <param name="name"></param>
        private void Remove(String name)
        {
            Loading = true;
            HttpGet httpGetRemoveSocialNetwork = new HttpGet(GlobalHelper.Url + String.Format("RemoveSocialNetworkAccount/{0}/{1}", UserHelper.Token, name), typeof(RemoveSocialNetworkAccountResult));
            httpGetRemoveSocialNetwork.FinishedGet += httpGetRemoveSocialNetwork_FinishedGet;
        }

        private void httpGetRemoveSocialNetwork_FinishedGet(object sender, EventArgs e)
        {
            Loading = false;
            ControllerHelper.SocialNetworkAccountController.Update();
            ControllerHelper.MyProfileController.Update();
        }
        
        public void CheckIfIsFinished(String url)
        {
            if (url.StartsWith(CurrentSocialNetworkToAuthenticate.AuthenticationFinishedURL))
                SendCode(url);
        }

        private void SendCode(String url)
        {
            Loading = true;
            HttpGet httpGetSendCode = new HttpGet(GlobalHelper.Url + String.Format("ValidateSocialNetworkAuthenticationURL/{0}/{1}?url={2}", UserHelper.Token, CurrentSocialNetworkToAuthenticate.Name, Convert.ToBase64String(Encoding.UTF8.GetBytes(url))), typeof(ValidateSocialNetworkAuthenticationURLResult), HttpGetMode.Mode1);
            httpGetSendCode.FinishedGet += httpGetSendCode_FinishedGet;
        }

        private void httpGetSendCode_FinishedGet(Object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get != null && (get.resultObject as ValidateSocialNetworkAuthenticationURLResult) != null)
                {
                    ValidateSocialNetworkAuthenticationURLResult result = (get.resultObject as ValidateSocialNetworkAuthenticationURLResult);
                    ControllerHelper.WebBrowserSocialNetworkController.IsValidURL = result.IsValid;
                }
            }
            catch (Exception ex) { }
            finally { Loading = false; }
        }


        public override void Update()
        {
            GetSocialNetworkAccounts();
            base.Update();
        }

    }
}
